<template>
	<view class="scroller-content">
		<view :class="['loading-box flex-center', { loading: status > 1 }]" :style="{
				height: `${move}px`,
				opacity: `${Math.abs(move)}`
			}">
			<view v-show="status === 2" class="loading-icon flex-center">
				<image src="https://image.meiye.art/pic_oxbZre1GCf0dWA3JJZfi4" mode=""></image>
				<!-- <text>努力加载中...</text> -->
			</view>
			<text v-if="status === 0">下拉刷新</text>
			<text v-else-if="status === 1">松开刷新</text>
			<text v-else-if="status === 3">加载成功</text>
		</view>
		<view class="scrollerbox" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
			<slot></slot>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			isLoading: {
				type: Boolean,
				required: true
			}
		},
		data() {
			return {
				winHeight: 2000,

				// 滑动距离
				move: 0,

				// 加载区域高度 触发点
				offset: 50,

				// 最大可下拉距离
				maxPull: 160,

				// 是否操作中
				action: false,

				// 0.初始  1.松开可刷新  2.刷新中  3.刷新成功
				status: 0,
			};
		},
		mounted() {
			const systemInfo = uni.getSystemInfoSync();
			if (systemInfo && systemInfo.screenHeight) {
				this.winHeight = systemInfo.screenHeight;
			}
		},
		watch: {
			isLoading(newVal) {
				// 父级传递刷新
				if (newVal) {
					this.status = 2;
					this.move = this.offset;
				} else {
					// 不刷新回弹动画
					this.status = 3;
					// 加载成功，露出350ms
					setTimeout(() => {
						this.close();
					}, 350);
				}
			}
		},
		methods: {
			touchstart(ev) {
				if (this.action) return;
				this.startY = ev.changedTouches[0].clientY;
			},
			touchmove(ev) {
				const {
					startY,
					winHeight,
					offset,
					maxPull
				} = this;

				const diffY = ev.changedTouches[0].clientY - startY;

				if (diffY < 0) return;

				// 阻尼算法 正弦函数0-90°段 0-1之间
				const rate = Math.sin(Math.PI * 0.5 * (diffY / winHeight));
				const move = maxPull * rate;

				this.move = move;
				this.status = move < offset ? 0 : 1;
			},
			touchend() {
				uni.createSelectorQuery().selectViewport().scrollOffset(res => {
					// console.log("竖直滚动位置" + res.scrollTop);
					if (res.scrollTop > 500) {
						this.close();
						return;
					};

					if (this.move > this.offset) {
						this.$emit('refresh');
						this.move = this.offset;
					} else {
						this.close();
					}
				}).exec();
			},
			close() {
				this.move = 0;
				this.action = false;
				this.status = 2;
				// 动画完成以后重置
				setTimeout(() => {
					this.status = 0;
				}, 300);
			},
			// 手动触发下拉刷新
			refresh() {
				this.status = 2;
				this.move = 100;

				setTimeout(() => {
					this.status = 3;
					// 加载成功，露出350ms
					setTimeout(() => {
						this.close();
					}, 350);
				}, 300);
			}
		}
	};
</script>

<style lang="scss" scoped>
	.flex-center {
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.loading-box {
		&.loading {
			transition: height .3s;
		}

		image {
			width: 150rpx;
			height: 100rpx;
			// animation: rightSpin 2s linear infinite both;
		}

		text {
			margin-left: 4px;
			font-size: 30rpx;
			color: #666;
			text-shadow: 1rpx 1rpx 4rpx #fff;
		}
	}

	@keyframes rightSpin {
		from {
			transform: rotate(0deg);
		}

		to {
			transform: rotate(360deg);
		}
	}

	.scroller-content::-webkit-scrollbar {
		display: none !important;
		width: 0 !important;
		height: 0 !important;
		-webkit-appearance: none;
		background: transparent;
	}
</style>